package be.pluyckx.batteryprogress.utils.calculator;

import be.pluyckx.batteryprogress.data.history.BatteryLevel;

/**
 * Created by Philip Luyckx on 6/08/13.
 */
public abstract class ProgressCalculator {

  public static final int TYPE_AVERAGE = 0;
  public static final int TYPE_REAL_TIME = 1;
  private static final String TAG = "ProgressCalculator";

  public abstract Result calculate(DataCollection data, Parameters params);

  public abstract Result calculate(DataCollection data, Parameters params, int index);

  protected Result average(DataItem oldest, DataItem newest) {
    if (oldest == null || newest == null || oldest == newest) {
      return null;
    }

    float diff = newest.getValue() - oldest.getValue();
    long elapsed = (newest.getElapsed() - oldest.getElapsed());
    float percentPerSecond = diff / elapsed;
    long secondsToGo = 0;
    if (percentPerSecond > 0) {
      secondsToGo = (long) Math.abs((1.0 - newest.getValue()) / percentPerSecond);
    } else {
      secondsToGo = (long) Math.abs(newest.getValue() / percentPerSecond);
    }

    return new Result(newest, oldest, secondsToGo, percentPerSecond * 3600.0f);
  }

  public static class Parameters {
    public static final int ORDERED_NEW_LOWEST_INDEX = 0;
    public static final int ORDERED_OLD_LOWEST_INDEX = 1;

    protected int mOrdered;

    public Parameters(int ordered) {
      mOrdered = ordered;
    }
  }

  public static class Result {
    private long mSecondsToGo;
    private float mPercentPerHour;
    private DataItem mNewest;
    private DataItem mOldest;

    public Result(DataItem newest, DataItem oldest, long secondsToGo, float percentPerHour) {
      mSecondsToGo = secondsToGo;
      mPercentPerHour = percentPerHour;
      mNewest = newest;
      mOldest = oldest;
    }

    public long getSecondsToGo() {
      return mSecondsToGo;
    }

    public float getPercentPerHour() {
      return mPercentPerHour;
    }

    public DataItem getNewestItem() {
      return mNewest;
    }

    public DataItem getOldestItem() {
      return mOldest;
    }
  }

  public static interface DataItem {
    public float getValue();

    public long getElapsed();

    public long getDate();

    public int getState();
  }

  public static interface DataCollection {
    public static final int STATE_CHARGING = BatteryLevel.STATE_CHARGING;
    public static final int STATE_DISCHARGING = BatteryLevel.STATE_DISCHARGING;

    public DataItem get(int index);

    public DataItem getFirstInCurrentState();

    public DataItem getLastInCurrentState();

    public int size();

    public int getOrdered();
  }
}
